package application

import (
	"bufio"
	log "github.com/sirupsen/logrus"
	"io"
	"os/exec"
	"strings"
	"sync"
	"usbipproxy/domain/service"
)

type ProgramServiceWindowsImpl struct {
	usbIpCmdSvc service.UsbIpServerCmdService
}

func (p *ProgramServiceWindowsImpl) Stop() error {
	rets := p.usbIpCmdSvc.List()
	for _, item := range rets {
		p.usbIpCmdSvc.UnBind(item.BusId)
	}
	return nil
}

func (p *ProgramServiceWindowsImpl) StartVBoxUsbMon() error {
	str, err := exec.Command("sc", "start", "VBoxUsbMon").CombinedOutput()
	if err != nil {
		log.Errorf("StartVBoxUsbMon err:%v", err)
		return nil
	}

	log.Infof("StartVBoxUsbMon str: %+v", string(str))
	return nil
}

/*
# 3. 加载必要的内核模块
sudo modprobe usbip-host
sudo modprobe usbip-core
sudo modprobe vhci-hcd
*/
func (p *ProgramServiceWindowsImpl) Start() error {
	//先把 sc query VBoxUsbMon 启动起来
	p.StartVBoxUsbMon()
	cmdStrs := []string{"usbipd", "server"}
	cmd := exec.Command(cmdStrs[0], cmdStrs[1:]...)

	// 创建管道获取标准输出
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Errorf("cmd.StdoutPipe err:%v", err)
	}

	stderr, err := cmd.StderrPipe()
	if err != nil {
		log.Errorf("cmd.StderrPipe err:%v", err)
	}

	// 启动命令
	if err := cmd.Start(); err != nil {
		log.Errorf("cmd.Start err:%v", err)
	}
	log.Infof("Waiting for command:%+v to finish...", cmdStrs)
	var wg sync.WaitGroup
	wg.Add(2)

	allList := p.usbIpCmdSvc.List()
	for _, item := range allList {
		p.usbIpCmdSvc.UnBind(item.BusId)
	}

	// 处理标准输出
	go func() {
		defer wg.Done()

		// 使用带缓冲的大读取器
		reader := bufio.NewReaderSize(stdout, 1024*64) // 64KB buffer
		for {
			// 使用 ReadBytes 而不是 Scanner
			line, err := reader.ReadBytes('\n')
			if err != nil {
				if err != io.EOF {
					log.Errorf("stdout读取错误: %v", err)
				}
				break
			}
			if len(line) > 0 {
				// 去除尾部的换行符
				log.Infof("usbipd stdout info: %s", strings.TrimSpace(string(line)))
			}
		}
	}()

	// 处理标准输出
	go func() {
		defer wg.Done()

		// 使用带缓冲的大读取器
		reader := bufio.NewReaderSize(stderr, 1024*64) // 64KB buffer
		for {
			// 使用 ReadBytes 而不是 Scanner
			line, err := reader.ReadBytes('\n')
			if err != nil {
				if err != io.EOF {
					log.Errorf("stderr 读取错误: %v", err)
				}
				break
			}
			if len(line) > 0 {
				// 去除尾部的换行符
				log.Infof("usbipd stderr info: %s", strings.TrimSpace(string(line)))
			}
		}
	}()

	// 等待命令结束
	if err := cmd.Wait(); err != nil {
		log.Errorf("ProgramServiceWindowsImpl cmd:%+v wait err:%v", cmdStrs, err)
	}

	// 等待输出处理完成
	wg.Wait()

	return nil
}

func NewProgramServiceWindowsImpl(usbIpCmdSvc service.UsbIpServerCmdService) ProgramService {
	return &ProgramServiceWindowsImpl{usbIpCmdSvc: usbIpCmdSvc}
}
